package com.ce.pms.house.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.ce.pms.base.service.impl.PmsBaseServiceImpl;
import com.ce.pms.common.model.SysrefcodeDO;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.house.dao.IGoodsRecordDao;
import com.ce.pms.house.dao.IReasonDefDao;
import com.ce.pms.house.model.GoodsRecordDomain;
import com.ce.pms.house.model.ReasonDefDomain;
import com.ce.pms.house.service.IGoOutService;
import com.ce.pms.house.vo.ReasonVO;
import com.ce.util.BlankUtil;
import com.sitechasia.webx.core.support.Page;

public class GoOutServiceImpl extends PmsBaseServiceImpl implements IGoOutService {
	private IReasonDefDao reasonDefDao;
	private IGoodsRecordDao goodsRecordDao;


	/**
	 * 方法描述: 根据异常类型查询相应异常集合
	 * @author 胡煦
	 * Create on:2008-9-4
	 * @param reasonDefType
	 * @return List<ReasonVO>
	 * Edit author:
	 * Edit on:
	 * 修改原因：
	 */
	public List<ReasonVO> getReasonDefDoList(String reasonDefType){
		List<ReasonDefDomain> reasonDefDoList = reasonDefDao.getReasonDefDoList(reasonDefType);
		List<ReasonVO> reasonVOList = new ArrayList<ReasonVO>();
		for(ReasonDefDomain reasonDefDomain : reasonDefDoList){
			ReasonVO reasonVO = this.reasonToVO(reasonDefDomain);
			reasonVOList.add(reasonVO);
		}
		return reasonVOList;
	}

	public String addGoOutException(ReasonVO vo) {
		SysrefcodeDO type = explainVoType(vo);
		ReasonDefDomain checkException = new ReasonDefDomain(type,vo.getSeqNo(),this.createInfo(vo.getOperator()));
		checkException.setDescription(vo.getDescription());
		checkException.setName(vo.getName());

		checkUnique(checkException);
		reasonDefDao.saveObject(checkException);

		return "true";
	}

	public String editGoOutException(ReasonVO vo) {
		ReasonDefDomain theReason = reasonDefDao.findById(vo.getId());
		//如已被引用，不能改名
		if (!theReason.getName().equals(vo.getName())) {
			checkUsed(theReason);
			theReason.setName(vo.getName());
		}

		theReason.setDescription(vo.getDescription());
		theReason.setSeqNo(vo.getSeqNo());
		this.modifyInfo(theReason.getSysInfo(),vo.getOperator());
		checkUnique(theReason);

		return "true";
	}
	private void checkUsed(ReasonDefDomain theReason) {
		if(reasonDefDao.isUsed(theReason)) {
			throw new BusinessException("house:exception_reference,"+theReason.getName());
		}
	}
	private void checkUnique(ReasonDefDomain theReason) {
		if(reasonDefDao.nameAlreadyExist(theReason)) {
			throw new BusinessException("house:exception_unique,"+theReason.getName());
		}
	}

	public String deleteGoOutException(Long id) {
		ReasonDefDomain theReason = reasonDefDao.findById(id);
		checkUsed(theReason);
		reasonDefDao.doDeleteById(id);
		return "true";
	}

	public Page showGoOutExceptions(ReasonVO vo, Integer pageNO, Integer pageSize) {
		String orderby = " SYSDATE DESC";
		if(!BlankUtil.isBlank(vo.getOrderString()))
			orderby = vo.getOrderString();

		List<Object> list = new ArrayList<Object>();
		StringBuffer hql = new StringBuffer("from ReasonDefDomain reason where 1=1");
		if(!BlankUtil.isBlank(vo.getName())) {
			hql.append(" and reason.name like ? ");
			list.add("%"+vo.getName()+"%");
		}
		if(!BlankUtil.isBlank(vo.getTypes())) {
			hql.append(" and reason.type=?");
			list.add(explainVoType(vo));
		}
		hql.append(" order by ").append(orderby);
		Page p = reasonDefDao.pagedQueryByPageNo(hql.toString(), pageNO, pageSize,list.toArray());
		reasonDomainToReasonVO(p);
		return p;
	}
	//根据vo中的异常参数返回相应的异常类型
	private SysrefcodeDO explainVoType(ReasonVO vo) {
		SysrefcodeDO type = null;
		if(SysrefcodeDO.CS_REASON_DEF_COPY_METER_REASON.equals(vo.getTypes())) {
			type = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_COPY_METER);
		}else if (SysrefcodeDO.CS_REASON_DEF_CHECK_HOUSE_REASON.equals(vo.getTypes())) {
			type = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_CHECK_HOUSE);
		}else if (SysrefcodeDO.CS_REASON_DEF_GOODS_TRANSFER_REASON.equals(vo.getTypes())) {
			type = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_GOODS_TRANSFER);
		}
		return type;
	}
	private String returnVoType(SysrefcodeDO type) {
		String retValue = null;
		if(!BlankUtil.isBlank(type)){
			if(type == this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_COPY_METER)){
				retValue = SysrefcodeDO.CS_REASON_DEF_COPY_METER_REASON;
			} else if(type == this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_CHECK_HOUSE)){
				retValue = SysrefcodeDO.CS_REASON_DEF_CHECK_HOUSE_REASON;
			}else if(type == this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_GOODS_TRANSFER)){
				retValue = SysrefcodeDO.CS_REASON_DEF_GOODS_TRANSFER_REASON;
			};
		}
		return retValue;
	}

	private SysrefcodeDO returnDoType(String type)
	{
		SysrefcodeDO sysRef = null;
		if(SysrefcodeDO.CS_REASON_DEF_COPY_METER_REASON.equals(type)){
			sysRef = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_COPY_METER);
		} else if(SysrefcodeDO.CS_REASON_DEF_CHECK_HOUSE_REASON.equals(type)){
			sysRef = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_CHECK_HOUSE);
		}else if(SysrefcodeDO.CS_REASON_DEF_GOODS_TRANSFER_REASON.equals(type)){
			sysRef = this.sysrefcodeDao.getSysrefCodesByCode("CS_REASON_DEF_REASON_TYPE", SysrefcodeDO.CS_REASON_DEF_REASON_TYPE_GOODS_TRANSFER);
		}
		return sysRef;
	}

	private void reasonDomainToReasonVO(Page domain) {
		List<ReasonVO> retValue = new ArrayList();
		List<ReasonDefDomain> result = domain.getResult();
		for(ReasonDefDomain reason:result) {
			retValue.add(reasonToVO(reason));
		}
		domain.setResult(retValue);
	}
	private ReasonVO reasonToVO(ReasonDefDomain reason) {
		ReasonVO vo = new ReasonVO();
		vo.setId(reason.getKeyword());
		vo.setDescription(reason.getDescription());
		vo.setName(reason.getName());
		vo.setSeqNo(reason.getSeqNo());
		vo.setTypes(returnVoType(reason.getType()));
		return vo;
	}


	public String addGoodsRecord(ReasonVO vo) {
		GoodsRecordDomain good = new GoodsRecordDomain(vo.getName(),vo.getSeqNo(),this.createInfo(vo.getOperator()));
		good.setRemark(vo.getDescription());
		checkUnique(good);
		goodsRecordDao.saveObject(good);
		return "true";
	}

	public String editGoodsRecord(ReasonVO vo) {
		GoodsRecordDomain good = goodsRecordDao.findById(vo.getId());
		if(!good.getName().equals(vo.getName())) {
			checkUsed(good);
			good.setName(vo.getName());
		}

		good.setRemark(vo.getDescription());
		good.setSeqNo(vo.getSeqNo());
		this.modifyInfo(good.getSysInfo(), vo.getOperator());

		checkUnique(good);
		return "true";
	}



	public String deleteGoodsRecord(Long id) {
		GoodsRecordDomain good = goodsRecordDao.findById(id);
		checkUsed(good);
		goodsRecordDao.deleteObjectById(id);
		return "true";
	}
	private void checkUsed(GoodsRecordDomain good) {
		if(goodsRecordDao.isUsed(good)) {
			throw new BusinessException("house:exception_reference,"+good.getName(),BusinessException.WARNING);
		}
	}
	private void checkUnique(GoodsRecordDomain good) {
		if(goodsRecordDao.nameAlreadyExist(good)) {
			throw new BusinessException("house:exception_unique,"+good.getName(),BusinessException.WARNING);
		}
	}

	public Page showGoodsRecords(ReasonVO vo, Integer pageNO, Integer pageSize) {
		String orderby = " SYSDATE DESC";
		if(!BlankUtil.isBlank(vo.getOrderString()))
			orderby = vo.getOrderString();
		StringBuffer hql = new StringBuffer("from GoodsRecordDomain good where 1=1");//? order by "+orderby;
		List<Object> list = new ArrayList<Object>();
		if(!BlankUtil.isBlank(vo.getName())) {
			hql.append(" and good.name like ? ");
			list.add("%"+vo.getName()+"%");
		}
		hql.append(" order by ")
		.append(orderby)
		.append(" desc");
		Page p = reasonDefDao.pagedQueryByPageNo(hql.toString(), pageNO, pageSize,list.toArray());
		goodDomainToReasonVO(p);
		return p;
	}

	private void goodDomainToReasonVO(Page p) {
		List<ReasonVO> retValue = new ArrayList();
		List<GoodsRecordDomain> result = p.getResult();
		for(GoodsRecordDomain good:result) {
			retValue.add(goodToVO(good));
		}
		p.setResult(retValue);
	}
	private ReasonVO goodToVO(GoodsRecordDomain good) {
		ReasonVO vo = new ReasonVO();
		vo.setId(good.getKeyword());
		vo.setDescription(good.getRemark());
		vo.setName(good.getName());
		vo.setSeqNo(good.getSeqNo());
		vo.setTypes(SysrefcodeDO.CS_REASON_DEF_GOODS_RECORD);
		return vo;
	}

	public ReasonVO findGoOutException(Long id) {
		return reasonToVO(reasonDefDao.findById(id));
	}

	public ReasonVO findGoodsRecord(Long id) {
		return goodToVO(goodsRecordDao.findById(id));
	}

	public void setGoodsRecordDao(IGoodsRecordDao goodsRecordDao) {
		this.goodsRecordDao = goodsRecordDao;
	}

	public void setReasonDefDao(IReasonDefDao reasonDefDao) {
		this.reasonDefDao = reasonDefDao;
	}

	public boolean checkUnique(ReasonVO vo) {
		boolean retValue = false;
		if (!BlankUtil.isBlank(vo.getTypes())) {
			//检查异常登记
			ReasonDefDomain checkException = new ReasonDefDomain();
			checkException.setName(vo.getName());
			checkException.setType(returnDoType(vo.getTypes()));
			if(!BlankUtil.isBlank(vo.getId())) {
				//修改
				checkException.setKeyword(vo.getId());
			}
			retValue = !reasonDefDao.nameAlreadyExist(checkException);

		} else {
			//检查物品移交
			GoodsRecordDomain good = new GoodsRecordDomain();
			good.setName(vo.getName());
			if(!BlankUtil.isBlank(vo.getId())) {
				//修改
				good.setKeyword(vo.getId());
			}
			retValue = !goodsRecordDao.nameAlreadyExist(good);
		};
		return retValue;
	}

	public boolean checkUsed(ReasonVO vo) {
		boolean retValue = false;
		if (!BlankUtil.isBlank(vo.getTypes())) {
			//检查异常登记
			ReasonDefDomain checkException = new ReasonDefDomain();
			checkException.setName(vo.getName());
			if(!BlankUtil.isBlank(vo.getId())) {
				//修改
				checkException.setKeyword(vo.getId());
			}
			retValue = reasonDefDao.isUsed(checkException);

		} else {
			//检查物品移交
			GoodsRecordDomain good = new GoodsRecordDomain();
			good.setName(vo.getName());
			if(!BlankUtil.isBlank(vo.getId())) {
				//修改
				good.setKeyword(vo.getId());
			}
			retValue = goodsRecordDao.isUsed(good);
		};
		return retValue;
	}



}
